package zpe.controledeacesso.jsf.view.bean;

import static zpe.genericcrud.jsf.view.bean.FacesUtils.addErrorMessage;
import static zpe.genericcrud.jsf.view.bean.FacesUtils.addWarnMessage;

import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;

import org.primefaces.model.DualListModel;

import zpe.controledeacesso.model.bean.Modulo;
import zpe.controledeacesso.model.bean.Transacao;
import zpe.controledeacesso.service.TransacaoService;
import zpe.genericcrud.exception.ApplicationException;
import zpe.genericcrud.jsf.view.bean.AbstractCrudBean;

@ManagedBean(name="transacaoBean")
@ViewScoped
public class TransacaoBean extends AbstractCrudBean<Transacao, TransacaoService> {

	@ManagedProperty("#{transacaoService}")
	protected TransacaoService service;

	private DualListModel<Modulo> moduloList;

	@Override
	public void setService(TransacaoService service) {
		super.setService(service);
	}

	@Override
	public void update(ActionEvent event) {
		try {
			if (getService().findTransacaoExistente(getEntity())) {
				throw new ApplicationException("Transação já cadastrada.");
			}

			getEntity().setModulos(moduloList.getTarget());
			super.update(event);
		} catch ( ApplicationException e ) {
			addErrorMessage( e.getMessage() );
		} catch ( Exception e ) {
			addErrorMessage( getMessage( "ERROR_INSERT" ) );
		}
	}

	@Override
	public void save(ActionEvent event) {
		try{
			if (getService().findTransacaoExistente(getEntity().getDescricao())) {
				throw new ApplicationException("Transação já cadastrada.");
			}
			getEntity().setModulos(moduloList.getTarget());
			super.save(event);
			preparaLista();
			getEntity().getModulos().clear();
		} catch ( ApplicationException e ) {
			addErrorMessage( e.getMessage() );
		} catch ( Exception e ) {
			addErrorMessage( getMessage( "ERROR_INSERT" ) );
		}
	}

	@Override
	public void prepareUpdate(ActionEvent event) {
		super.prepareUpdate(event);
		preparaLista();
	}

	@Override
	public void prepareInsert(ActionEvent event) {
		//setModulos(new ArrayList<Modulo>());
		super.prepareInsert(event);
		preparaLista();		
	}

	private void preparaLista(){

		moduloList = new DualListModel<Modulo>();
		List<Modulo> modulos = getService().findModulos();
		moduloList.setSource(modulos);
		moduloList.setTarget(getEntity().getModulos());

		for (Modulo m : getEntity().getModulos()) {
			moduloList.getSource().remove(m);
		}

	}

	@SuppressWarnings("unchecked")
	@Override
	public void find(ActionEvent event) {
		try{
			limpaListas();
			if( getEntitySearch().getDescricao() != null || ( getEntitySearch().getModulo() != null && getEntitySearch().getModulo().getId() != null ) ){
				List<Transacao> list = getService().findByFilter( getEntitySearch() );
				if( !list.isEmpty() ){
					getResultSearch().setWrappedData(list);
					setOriginalResult( (List<Transacao>)getResultSearch().getWrappedData() );
				}else{
					addWarnMessage( getMessage( "NOT_FOUND" ) );
				}
				setCurrentState( STATE_SEARCH );
			}else{
				addErrorMessage( "É necessário preencher pelo menos um dos campos para consulta." );
			}
		}catch (Exception e) {
			addErrorMessage( getMessage( "ERROR_MESSAGE" ) );
		}
	}

	public DualListModel<Modulo> getModuloList() {
		return moduloList;
	}

	public void setModuloList(DualListModel<Modulo> moduloList) {
		this.moduloList = moduloList;
	}
}
